﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MjpegProcessor;
using System.Drawing;
using System.Windows.Media.Imaging;
using OVS_Tools;
using System.Threading;
using System.Windows.Media;
using OVS_FormsRecognition.Manager;
using OVS.BusinessObjects;
using AForge.Video;

namespace OVS_FormsRecognition.Objects
{
    /// <summary>
    /// Objet contenant se qui est utile pour géré les camera IP
    /// </summary>
    public class CameraFromMjpegDecoder : EventArgs
    {

        private static readonly log4net.ILog _Log = log4net.LogManager.GetLogger(typeof(CameraFromMjpegDecoder));
        private string camPath;

        //public DetectEventArgs NewFrameFromCamAllow;

        /// <summary>
        /// The haartainning files liste
        /// </summary>
        public List<Image_Haar> HaartainningFilesListe;

        /// <summary>
        /// Gets or sets the mjpeg decoder.
        /// </summary>
        /// <value>
        /// The mjpeg decoder.
        /// </value>
        public MjpegDecoder MjpegDecoder { get; set; }

        /// <summary>
        /// Gets or sets the camera id.
        /// </summary>
        /// <value>
        /// The camera id.
        /// </value>
        public int CameraId { get; set; }

        /// <summary>
        /// Gets or sets the current frame.
        /// </summary>
        /// <value>
        /// The current frame.
        /// </value>
        public Bitmap currentFrame { get; set; }

       

        // Declare the delegate (if using non-generic pattern).
        public delegate void NewFrameFromCamHandler(object sender, CameraFromMjpegDecoder e);

        // Declare the event.
        public event NewFrameFromCamHandler NewFrameFromCamEvent;



        /// <summary>
        /// The detect object
        /// </summary>
        public bool detectObject;


        /// <summary>
        /// The fram counter
        /// </summary>
        public int FramCounter;

        /// <summary>
        /// The counter
        /// </summary>
        public int counter;


        /// <summary>
        /// The pool
        /// </summary>
        public Dictionary<int, ThreadDetecor> pool;

        /// <summary>
        /// The current thread id in pool
        /// </summary>
        public int currentThreadIdInPool;
        /// <summary>
        /// The is new frame
        /// </summary>
        public bool isNewFrame;
        /// <summary>
        /// The stream
        /// </summary>
        private MJPEGStream stream;

        /// <summary>
        /// Gets or sets a value indicating whether this instance is in test mode.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is in test mode; otherwise, <c>false</c>.
        /// </value>
        public bool isInTestMode { get; set; }

        /// <summary>
        /// Initializes a new instance of the <see cref="CameraFromMjpegDecoder" /> class.
        /// </summary>
        /// <param name="pCameraId">The p camera id.</param>
        /// <param name="pMjpegDecoder">The p mjpeg decoder.</param>
        public CameraFromMjpegDecoder(int pCameraId, String pCamPath)
        {

            CameraId = pCameraId;
            camPath = pCamPath;
        }

        public void UpdateCurrentFrame(object sender, NewFrameEventArgs e)
        {
            try
            {

                if (e == null)
                {
                    _Log.Warn("UpdateCurrentFrame: Exception" + sender);
                    UnregisterListenner();
                    RegisterListenner();
                }
                else
                {
                    if (e.Frame == null)
                        return;
                    if (e.Frame.Size == Size.Empty)
                        return;

                    MjpegDecoder.Bitmap = e.Frame;//ImageHelper.GetBitmap(e.BitmapImage);

                    if (NewFrameFromCamEvent != null)
                        NewFrameFromCamEvent(null, this);
                }


            }

            catch (Exception ex)
            {
                _Log.WarnFormat("updateCurrentFrame" + ex);
            }


        }

        internal void InitObject()
        {
            try
            {
                if (MjpegDecoder == null)
                    MjpegDecoder = new MjpegDecoder();
                RegisterListenner();

                //workerDetectors = new Dictionary<int, Thread>();
            }
            catch (Exception ex)
            {
                _Log.WarnFormat("new CameraFromMjpegDecoder(int {0}, String {1})", CameraId, camPath);
            }
        }

        public void RegisterListenner()
        {
            //if (MjpegDecoder == null) return;

            // create MJPEG video source
            stream = new MJPEGStream(camPath);
            // set event handlers
            stream.NewFrame += new NewFrameEventHandler(UpdateCurrentFrame);
            // start the video source
            stream.Start();
            // ...
           
            try
            {
               
                // start the video source
                stream.Start();
            }
            catch (Exception e)
            {
                _Log.Warn("CameraFromMjpegDecoder: RegisterListenner(): Exception: " + e);              
            }

            //_Log.DebugFormat("RegisterListenner(camId: {0})", CameraId);
        }
        public void UnregisterListenner()
        {
            if (MjpegDecoder == null) return;
            //MjpegDecoder.FrameReady -= UpdateCurrentFrame;
            //_Log.DebugFormat("UnregisterListenner(camId: {0})", CameraId);

            // signal to stop
            stream.SignalToStop();
        }





    }
}
